﻿using CsvHelper.Configuration;

namespace AIC_Notification
{
    public class SchoolAdmissionStatistics
    {
        public enum SchoolListType { Unknown, Safety, Match, Reach, SuperReach };

        public string SchoolName    { get; set; }
        public int    Normal_Count  { get; set; }
        public double SAT_Mean      { get; set; }
        public double SAT_Median    { get; set; }
        public double SAT_Std       { get; set; }
        public double SAT_Min       { get; set; }
        public double SAT_Max       { get; set; }
        public double TOEFL_Mean    { get; set; }
        public double TOEFL_Median  { get; set; }
        public double TOEFL_Std     { get; set; }
        public double TOEFL_Min     { get; set; }
        public double TOEFL_Max     { get; set; }
        public int    Safety_Count      { get; set; }
        public double Safety_SAT_Mean   { get; set; }
        public double Safety_SAT_Std    { get; set; }
        public double Safety_TOEFL_Mean { get; set; }
        public double Safety_TOEFL_Std  { get; set; }

        public SchoolAdmissionStatistics()
        {
        }

        public SchoolListType GetSafetySchoolType(int SAT_Score, int TOEFL_Score)
        {
            SchoolListType SATListType = SchoolListType.Unknown;
            SchoolListType TOEFLListType = SchoolListType.Unknown;

            if (Safety_Count > 0)
            {
                if (SAT_Score > 0)
                {
                    if (SAT_Score > Safety_SAT_Mean - Safety_SAT_Std)
                        SATListType = SchoolListType.Safety;
                }

                if (TOEFL_Score > 0)
                {
                    if (TOEFL_Score > Safety_TOEFL_Mean - Safety_TOEFL_Std)
                        TOEFLListType = SchoolListType.Safety;
                }

                if (SAT_Score > 0 && TOEFL_Score > 0)
                {
                    if ((SATListType == SchoolListType.Safety) && (TOEFLListType == SchoolListType.Safety))
                        return SchoolListType.Safety;
                    else
                        return SchoolListType.Unknown;
                }
                else if (SAT_Score > 0 && TOEFL_Score == 0)
                {
                    return SATListType;
                }
                else if (SAT_Score == 0 && TOEFL_Score > 0)
                {
                    return TOEFLListType;
                }
                else
                    return SchoolListType.Unknown;
            }
            else
                return SchoolListType.Unknown;
        }

        public SchoolListType GetSchoolType(int SAT_Score, int TOEFL_Score)
        {
            SchoolListType SATListType = SchoolListType.Unknown;
            SchoolListType TOEFLListType = SchoolListType.Unknown;

            // Calculate SAT Type
            if (SAT_Score > 0)
            {
                if (SAT_Score < SAT_Min)
                {
                    SATListType = SchoolListType.SuperReach;
                }
                else if ((SAT_Score >= SAT_Min) && (SAT_Score < SAT_Mean - SAT_Std))
                {
                    SATListType = SchoolListType.Reach;
                }
                else if ((SAT_Score >= SAT_Mean - SAT_Std) && (SAT_Score < SAT_Mean + SAT_Std))
                {
                    if (Safety_Count > 0)  // Can be a safety school
                    {
                        if (SAT_Score > Safety_SAT_Mean - Safety_SAT_Std)
                            SATListType = SchoolListType.Safety;
                        else
                            SATListType = SchoolListType.Match;
                    }
                    else
                        SATListType = SchoolListType.Match;
                }
                else if (SAT_Score >= SAT_Mean + SAT_Std)
                {
                    SATListType = SchoolListType.Safety;
                }
            }

            // Calculate TOEFL Type
            if (TOEFL_Score > 0)
            {
                if (TOEFL_Score < TOEFL_Min)
                {
                    TOEFLListType = SchoolListType.SuperReach;
                }
                else if ((TOEFL_Score >= TOEFL_Min) && (TOEFL_Score < TOEFL_Mean - TOEFL_Std))
                {
                    TOEFLListType = SchoolListType.Reach;
                }
                else if ((TOEFL_Score >= TOEFL_Mean - TOEFL_Std) && (TOEFL_Score < TOEFL_Mean + TOEFL_Std))
                {
                    if (Safety_Count > 0)  // Can be a safety school
                    {
                        if (TOEFL_Score > Safety_TOEFL_Mean - Safety_TOEFL_Std)
                            TOEFLListType = SchoolListType.Safety;
                        else
                            TOEFLListType = SchoolListType.Match;
                    }
                    else
                        TOEFLListType = SchoolListType.Match;
                }
                else if (TOEFL_Score >= TOEFL_Mean + TOEFL_Std)
                {
                    TOEFLListType = SchoolListType.Safety;
                }
            }

            // Determin what to return
            if (SATListType != SchoolListType.Unknown && TOEFLListType != SchoolListType.Unknown) // Has both
            {
                if (SATListType == TOEFLListType)
                    return SATListType;
                else
                {
                    return SATListType > TOEFLListType ? SATListType : TOEFLListType;
                }
            }
            else if (SATListType != SchoolListType.Unknown && TOEFLListType == SchoolListType.Unknown) // Only has SAT
            {
                    return SATListType;
            }
            else if (SATListType == SchoolListType.Unknown && TOEFLListType != SchoolListType.Unknown) // Only has TOEFL
            {
                return TOEFLListType;
            }
            else // Has none
            {
                return SchoolListType.Unknown;
            }
        }
    }

    public sealed class AdmissionResultMap : ClassMap<SchoolAdmissionStatistics>
    {
        public AdmissionResultMap()
        {
            Map(m => m.SchoolName).Index(0);
            Map(m => m.Normal_Count).Index(1);
            Map(m => m.SAT_Mean).Index(2);
            Map(m => m.SAT_Median).Index(3);
            Map(m => m.SAT_Std).Index(4);
            Map(m => m.SAT_Min).Index(5);
            Map(m => m.SAT_Max).Index(6);
            Map(m => m.TOEFL_Mean).Index(7);
            Map(m => m.TOEFL_Median).Index(8);
            Map(m => m.TOEFL_Std).Index(9);
            Map(m => m.TOEFL_Min).Index(10);
            Map(m => m.TOEFL_Max).Index(11);
            Map(m => m.Safety_Count).Index(12);
            Map(m => m.Safety_SAT_Mean).Index(13);
            Map(m => m.Safety_SAT_Std).Index(14);
            Map(m => m.Safety_TOEFL_Mean).Index(15);
            Map(m => m.Safety_TOEFL_Std).Index(16);
        }
    }
}
